package com.example.springbootdemo.config;

import com.example.springbootdemo.constant.RabbitmqConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * <p>
 *  rabbitmq配置类
 * </p>
 *
 * @author yurenwei
 * @since 2023/9/6
 */
@Slf4j
@Configuration
public class RabbitmqConfig {

    @Autowired
    private ConnectionFactory connectionFactory;

    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            log.info("【correlationData】:" + correlationData);
            log.info("【ack】" + ack);
            log.info("【cause】" + cause);
            if (ack) {
                log.info("【消息从生产者到交换机发送成功】");
            } else {
                log.info("【消息从生产者到交换机发送失败】correlationData:" + correlationData + " cause:" + cause);
            }
        });
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            log.warn("【消息从交换机到队列发送失败】");
            log.info("【message】" + message);
            log.info("【replyCode】" + replyCode);
        });

        return rabbitTemplate;
    }


    /**
     * 创建交换机
     *
     * @return Exchange
     */
    @Bean("testExChange")
    public Exchange testExChange() {
        return ExchangeBuilder
                .directExchange(RabbitmqConstant.TEST_EXCHANGE_NAME)
                .durable(true)
                .build();
    }

    /**
     * 创建队列
     *
     * @return Queue
     */
    @Bean("testQueue")
    public Queue testQueue() {
        return new Queue(RabbitmqConstant.TEST_QUEUE_NAME);
    }

    /**
     * 交换机绑定队列
     *
     * @param exchange 交换机
     * @param queue 对列
     * @return Binding
     */
    @Bean
    public Binding bind(@Qualifier("testExChange") Exchange exchange, @Qualifier("testQueue") Queue queue) {
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with(RabbitmqConstant.TEST_ROUTING_KEY)
                .noargs();
    }

}
